<script setup>
import { onMounted, onUnmounted, ref } from 'vue'
import * as PIXI from 'pixi.js'
import { Live2DModel } from 'pixi-live2d-display/cubism4'

// 👇 绑定 canvas 元素
const canvasRef = ref(null)
let app = null
let model = null // 存储模型实例
let ticker = null // ← 这里新增声明


let mouthValue = 0 // 0~1，控制嘴巴开合

// 模型路径（放在 public 目录下）
//const MODEL_PATH = '/live2d/hiyori_free_zh/model/hiyori_free_t08.model3.json'
const MODEL_PATH = '/live2d/Haru/Haru.model3.json'

// ✅ 必须：暴露 PIXI 到 window，供 pixi-live2d-display 内部使用
window.PIXI = PIXI

// 👉 嘴巴参数名（标准 Cubism 4 参数）
const PARAM_MOUTH_OPEN_Y = 'ParamMouthOpenY' // 控制嘴巴上下开合

onMounted(async () => {
  const canvas = canvasRef.value
  if (!canvas) return

  try {
    // 创建 PixiJS 应用（使用固定宽高或响应式）
    app = new PIXI.Application({
      view: canvas,
      autoStart: true,
      backgroundAlpha: 0,
      width: 800,
      height: 600,
      antialias: true,
      resolution: window.devicePixelRatio || 1
    })

    // 加载模型
    model = await Live2DModel.from(MODEL_PATH)

    // 添加到舞台
    app.stage.addChild(model)

    // === 🔍 自动适配模型大小 ===
    fitModelToView(model, app.screen.width, app.screen.height)
    // 用 app.ticker 实现嘴巴动画 // ticker 只根据 mouthValue 控制嘴巴
    ticker = (delta) => {
      if (model) {
        // 阻止动作覆盖嘴巴参数
        if (model.internalModel.motionManager) {
          model.internalModel.motionManager.update = () => {}
        }
        model.internalModel.coreModel.setParameterValueById(PARAM_MOUTH_OPEN_Y, mouthValue)
      }
    }
    app.ticker.add(ticker)

    // 交互事件
    // model.on('hit', async (hitAreas) => {
    //   if (hitAreas.includes('Body')) {
    //     console.log('点击了身体')
    //     try {
    //       await model.motion('TapBody')
    //       console.log('✅ 动作播放成功')
    //     } catch (err) {
    //       console.error('❌ 动作播放失败:', err)
    //     }
    //   }
    //   if (hitAreas.includes('Head')) {
    //     console.log('点击了头部')
    //     try {
    //       await model.expression('F03')
    //       console.log('✅ 动作播放成功')
    //     } catch (err) {
    //       console.error('❌ 动作播放失败:', err)
    //     }
    //   }

    // })
  } catch (error) {
    console.error('加载模型失败:', error)
  }
})

// 核心函数：自动适配模型到可视区域，并增加放大效果
function fitModelToView(model, viewportWidth, viewportHeight) {
  // 获取模型的包围盒（包含所有部件的实际渲染区域）
  const bounds = model.getBounds()

  const modelWidth = bounds.width
  const modelHeight = bounds.height

  // 留出边距
  const padding = 1.2

  // 放大系数，大于1表示放大，默认设置为1.2倍
  const zoomFactor = 1.2;

  // 计算缩放比例，使模型完整显示在窗口内
  const scaleX = (viewportWidth * zoomFactor) / modelWidth
  const scaleY = (viewportHeight * zoomFactor) / modelHeight
  const scale = Math.min(scaleX, scaleY) / padding // 取最小值并加边距

  // 设置缩放
  model.scale.set(scale)

  // 居中显示
  model.x = viewportWidth / 2
  model.y = viewportHeight / 2

  // 可选：设置锚点居中（如果模型偏移严重）
  model.anchor.set(0.5, 0.5)
}


onUnmounted(() => {
  if (app) {
    app.destroy(true, { textures: true, baseTexture: true })
    app = null
  }
})
</script>

<template>
  <canvas
    ref="canvasRef"
    class="live2d-canvas"
    width="800"
    height="600"
  ></canvas>
</template>

<style scoped>
.live2d-canvas {
  display: block;
  margin: 20px auto;
  max-width: 100%;
  height: auto;
  border: 1px solid #ddd;
  border-radius: 8px;
}
</style>